package com.xiaozhichao.javaapi.designpattern.singleton;

/**
 * 单例模式
 */
public class Singleton {

    /**
     * 构造函数私有化
     */
    private Singleton() {
    }

    /**
     * 静态工程方法，创建实例
     */
    private static Singleton instance = null;
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    /**
     *  线程安全，但是效率不行，只有对象第一次创建时才需要加锁
     * @return
     */
    public static synchronized Singleton getInstance1() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    /**
     *  线程安全，解决了效率问题
     *  但是  在Java指令中创建对象和赋值操作是分开进行的，也就是说instance = new Singleton();语句是分两步执行的
     *  值得怀疑
     * @return
     */
    public static Singleton getInstance2() {
        if (instance == null) {
            synchronized (instance) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    /**
     * 内部类的方式，线程安全
     * JVM内部的机制能够保证当一个类被加载的时候，这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候，JVM能够帮我们保证instance只被创建一次，并且会保证把赋值给instance的内存初始化完毕，这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制，这样就解决了低性能问题。这样我们暂时总结一个完美的单例模式
     */
    private static class SingletonFactory{
        private static Singleton instance = new Singleton();
    }
    public static Singleton getInstance3(){
        return SingletonFactory.instance;
    }

}
